#ifndef BGAIMAGEPROCESS_H
#define BGAIMAGEPROCESS_H
#include "Utils/singleton.h"
//#include "pgalayoutmanager.h"
#include "HalconCpp.h"
#include <QString>
#include <QtWidgets>

//#include "inspectparammanager.h"
#include "resultmanager.h"
#include "bgapackagemanager.h"


class BgaImageProcess : public QObject, public Singleton<BgaImageProcess>
{
	Q_OBJECT
public:
	typedef struct _INSPECT_RESULT {
		int countBallMiss;
		//	int countBallDamaged;
		HalconCpp::HRegion regionDamagedBall;
		HalconCpp::HRegion regionDamagedEdge;
		HalconCpp::HRegion regionCap;
		HalconCpp::HImage resultImage;
		int countCap;
	}INSPECT_RESULT;




	enum FAIL_REASON
	{
		FAIL_BALL_MISS,
		FAIL_BALL_NOT_ROUND,
		FAIL_BALL_TOO_SMALL,
		FAIL_BALL_TOO_BIG,
		
		FAIL_BALL_SHADOW_TOO_BIG,
		//FAIL_BALL_CIRCULARITY,
		FAIL_BALL_CM,
		FAIL_BALL_CRESCENT,
		FAIL_CAP_AREA,
		FAIL_SUBSTRATE_AREA,
		FAIL_REASON_NUM,
	};

	enum CRITICAL_REASON
	{
		CRITICAL_BALL_TOO_SMALL,
		CRITICAL_BALL_TOO_BIG,
		CRITICAL_BALL_NOT_ROUND,
		CRITICAL_BALL_SHADOW_TOO_BIG,
	};

	typedef struct _CRITICAL_ENTITY {
		QPointF coordinate;
		CRITICAL_REASON reason;
		QString reasonDesc;
		QString parameterDesc;
		union _MyUnion
		{
		//	int cirularity;
			double areaRatio;
			double shadowRatio;
			int substrateArea;
			double circularity;
		}value;
	}CRITICAL_ENTITY;

	typedef struct _INSPECT_ENTITY {
		QPointF coordinate;
		FAIL_REASON reason;
		QString reasonDesc;
		QString parameterDesc;
		union _MyUnion
		{
			//	int cirularity;
			double areaRatio;
			double shadowRatio;
			int substrateArea;
			double circularity;
		}value;
	}INSPECT_ENTITY;
	QList<INSPECT_ENTITY> m_listInspectEntity;
	QList<CRITICAL_ENTITY> m_listCriticalEntity;
	
	RUN_INFO m_ri;
	int m_iVerifyCount;
	int m_iInspectCount;
	void SetWinHandleAndSavePath(QWidget *widget, QString path, QDateTime time, RUN_INFO ri);
	
	void SetSubstrateImage(HalconCpp::HImage image, int index)
	{
		/*int k = index - m_substrateImageList.count();
		for (int i = 0; i < k; i++)*/
		{
			m_substrateImageList.append(image);
		}
		
		m_substrateImage = m_substrateImageList.first();
		//	m_substrateImageOrigin = m_substrateImage = image;

		qDebug() << __FUNCTION__;
		if (!image.IsInitialized())
		{
			return;
		}
		//m_substrateImage = image;
#ifdef  QT_NO_DEBUG
		QString appName = QCoreApplication::applicationName();
		QSettings app(appName, "Debug");
		int t = app.value("tempimage").toInt();
		if (t == 1)
		{
			QStringList list = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation);
			QString path = QString("%1/1_edge%2").arg(list.first()).arg(index);
			image.WriteImage("bmp", 0, path.toStdString().c_str());
	}
#else
		QStringList list = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation);
		QString path = QString("%1/1_edge%2").arg(list.first()).arg(index);
		image.WriteImage("bmp", 0, path.toStdString().c_str());
#endif
}
//	void SetCrossMarkImage(HalconCpp::HImage image, int index)
//	{
//		int k = index - m_crossMarkImageList.count();
//		for (int i = 0; i < k; i++)
//		{
//			m_crossMarkImageList.append(image);
//		}
//		
//		m_crossMarkImage = m_crossMarkImageList.first();
//		//	m_crossMarkImageOrigin = m_crossMarkImage = image;
//
//			//m_crossMarkImage = image;
//		qDebug() << __FUNCTION__;
//		if (!image.IsInitialized())
//		{
//			return;
//		}
//#ifdef  QT_NO_DEBUG
//		QString appName = QCoreApplication::applicationName();
//		QSettings app(appName, "Debug");
//		int t = app.value("tempimage").toInt();
//		if (t == 1)
//		{
//			QStringList list = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation);
//			QString path = QString("%1/1_cm%2").arg(list.first()).arg(index);
//			image.WriteImage("bmp", 0, path.toStdString().c_str());
//	}
//#else
//		QStringList list = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation);
//		QString path = QString("%1/1_cm%2").arg(list.first()).arg(index);
//		image.WriteImage("bmp", 0, path.toStdString().c_str());
//#endif
//	}

	void SetBallImage(HalconCpp::HImage image, int index)
	{
	/*	int k = index - m_ballImageList.count();
		for (int i = 0; i < k; i++)*/
		{
			m_ballImageList.append(image);
		}
	//	m_ballImageList.append(image);
		m_ballImage = m_ballImageList.first();
		//	m_ballImageOrigin = m_ballImage = image;

		qDebug() << __FUNCTION__;
		if (!image.IsInitialized())
		{
			return;
		}
#ifdef  QT_NO_DEBUG
		QString appName = QCoreApplication::applicationName();
		QSettings app(appName, "Debug");
		int t = app.value("tempimage").toInt();
		if (t == 1)
		{
			QStringList list = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation);
			QString path = QString("%1/1_ball%2").arg(list.first()).arg(index);
			image.WriteImage("bmp", 0, path.toStdString().c_str());
		}
#else
		QStringList list = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation);
		QString path = QString("%1/1_ball%2").arg(list.first()).arg(index);
		image.WriteImage("bmp", 0, path.toStdString().c_str());
#endif
	}
	void SetCapImage(HalconCpp::HImage image, int index)
	{
		/*int k = index - m_capImageList.count();
		for (int i = 0; i < k; i++)*/
		{
			m_capImageList.append(image);
		}
		m_capImage = m_capImageList.first();
		//m_capImageOrigin = m_capImage = image;

		qDebug() << __FUNCTION__;
		if (!image.IsInitialized())
		{
			return;
		}
#ifdef  QT_NO_DEBUG
		QString appName = QCoreApplication::applicationName();
		QSettings app(appName, "Debug");
		int t = app.value("tempimage").toInt();
		if (t == 1)
		{
			QStringList list = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation);
			QString path = QString("%1/1_cap%2").arg(list.first()).arg(index);
			image.WriteImage("bmp", 0, path.toStdString().c_str());
		}
#else
		QStringList list = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation);
		QString path = QString("%1/1_cap%2").arg(list.first()).arg(index);
		image.WriteImage("bmp", 0, path.toStdString().c_str());
#endif
	}
	ResultManager::ERROR_TYPE BgaImageProcess::GetLastResult()
	{
		return m_curRes;
	}
	bool InitParameter();
	void ResetVerifyTest();
	ResultManager::ERROR_TYPE GetInspectResult();
	//double GetCapMeanArea(HalconCpp::HImage imgCap);
	BgaPackageManager::POD_INFO GetPod();
	void DrawResultToWindow();
	signals:
		void UpdateMainWndEvent();
protected:
	friend class Singleton<BgaImageProcess>;
	BgaImageProcess();
private:

	QList<HalconCpp::HImage> m_substrateImageList;
	QList<HalconCpp::HImage> m_crossMarkImageList;
	QList<HalconCpp::HImage> m_ballImageList;
	QList<HalconCpp::HImage> m_capImageList;

	HalconCpp::HImage m_substrateImage;
	HalconCpp::HImage m_crossMarkImage;
	HalconCpp::HImage m_ballImage;
	HalconCpp::HImage m_capImage;

	//HalconCpp::HImage m_substrateImageOrigin;
	//HalconCpp::HImage m_crossMarkImageOrigin;
	//HalconCpp::HImage m_ballImageOrigin;
	//HalconCpp::HImage m_capImageOrigin;

	QWidget *m_widget;
	QString m_path;
	QDateTime m_time;
	double m_meanGray = 0;

	HalconCpp::HRegion m_regionAllCaps;
	HalconCpp::HRegion m_regionSubstrate;

	HalconCpp::HRegion m_regionAllBalls;

	BgaPackageManager::INSPECT_PARAM m_inspectParam;
	INSPECT_RESULT m_resultParam;
	BgaPackageManager::POD_INFO m_pod;

	void SaveResultImage(ResultManager::ERROR_TYPE res);
	void CheckAllBalls();
	BOOL CheckBallCrossMark(HalconCpp::HImage image);

	BOOL CheckCapacitorsBase(double threshold, double min, double max, int filter, double dif);
	BOOL CheckCapacitors2();
	BOOL CheckCapacitorsT28();

	void GenFullImageT28();
	void GenFullImageT32();
	HalconCpp::HRegion GetBallsRegions(HalconCpp::HImage image);

	HalconCpp::HRegion GetCapsRegionNew(HalconCpp::HImage imgCap);
	void CheckBallShadow(HalconCpp::HRegion regionSelect);
	void CheckSubstrate(HalconCpp::HImage image);
	void GenVerifyTestResult(ResultManager::ERROR_TYPE res);
	ResultManager::ERROR_TYPE m_curRes;
	void SaveImage(HalconCpp::HImage img, HalconCpp::HRegion reg, QString name);
};

#endif // BGAIMAGEPROCESS_H
